package org.springcloud.plugin.framework.strategy.adapter;

import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springcloud.plugin.common.constant.DiscoveryConstant;
import org.springcloud.plugin.common.util.JsonUtil;
import org.springcloud.plugin.common.util.StringUtil;
import org.springcloud.plugin.framework.adapter.CoreAdapter;
import org.springcloud.plugin.framework.context.PluginContextHolder;
import org.springcloud.plugin.framework.strategy.matcher.DiscoveryMatcherStrategy;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

/**
 * @Author yanggld
 * @Date 2020/1/21-18:30
 * @Description
 */
@Slf4j
public class DefaultDiscoveryEnabledAdapter implements DiscoveryEnabledAdapter {

	@Autowired(required = false)
	private DiscoveryEnabledStrategy discoveryEnabledStrategy;
	@Autowired
	private DiscoveryMatcherStrategy discoveryMatcherStrategy;
	@Autowired
	protected PluginContextHolder pluginContextHolder;
	@Autowired
	protected CoreAdapter coreAdapter;

	@Override
	public boolean apply(Server server) {
		boolean enabled = applyVersion(server);
		if (!enabled) {
			String serverServiceId = coreAdapter.getServerServiceId(server);
			log.warn("服务{"+serverServiceId+" [ "+server.getHostPort()+" ]}版本策略未通过");
			return false;
		}
		enabled = applyRegion(server);
		if (!enabled) {
			String serverServiceId = coreAdapter.getServerServiceId(server);
			log.warn("服务{"+serverServiceId+" [ "+server.getHostPort()+" ]}区域策略未通过");
			return false;
		}
		enabled = applyStrategy(server);
		if (enabled) {
			String serverServiceId = coreAdapter.getServerServiceId(server);
			log.warn("服务{"+serverServiceId+" [ "+server.getHostPort()+" ]}通过策略");
		}
		return enabled;
	}

	private boolean applyVersion(Server server) {
		String versionValue = pluginContextHolder.getContextRouteVersion();
		if (StringUtils.isEmpty(versionValue)) {
			return true;
		}

		String serviceId = coreAdapter.getServerServiceId(server);
		String version = coreAdapter.getServerVersion(server);

		String versions = null;
		try {
			Map<String, String> versionMap = JsonUtil.fromJson(versionValue, Map.class);
			versions = versionMap.get(serviceId);
		} catch (Exception e) {
			versions = versionValue;
		}

		if (StringUtils.isEmpty(versions)) {
			return true;
		}

		// 如果精确匹配不满足，尝试用通配符匹配
		List<String> versionList = StringUtil.splitToList(versions, DiscoveryConstant.SEPARATE);
		if (versionList.contains(version)) {
			return true;
		}

		// 通配符匹配。前者是通配表达式，后者是具体值
		for (String versionPattern : versionList) {
			if (discoveryMatcherStrategy.match(versionPattern, version)) {
				return true;
			}
		}

		return false;
	}

	private boolean applyRegion(Server server) {
		String regionValue = pluginContextHolder.getContextRouteRegion();
		if (StringUtils.isEmpty(regionValue)) {
			return true;
		}

		String serviceId = coreAdapter.getServerServiceId(server);
		String region = coreAdapter.getServerRegion(server);

		String regions = null;
		try {
			Map<String, String> regionMap = JsonUtil.fromJson(regionValue, Map.class);
			regions = regionMap.get(serviceId);
		} catch (Exception e) {
			regions = regionValue;
		}

		if (StringUtils.isEmpty(regions)) {
			return true;
		}

		// 如果精确匹配不满足，尝试用通配符匹配
		List<String> regionList = StringUtil.splitToList(regions, DiscoveryConstant.SEPARATE);
		if (regionList.contains(region)) {
			return true;
		}

		// 通配符匹配。前者是通配表达式，后者是具体值
		for (String regionPattern : regionList) {
			if (discoveryMatcherStrategy.match(regionPattern, region)) {
				return true;
			}
		}

		return false;
	}


	private boolean applyStrategy(Server server) {
		if (discoveryEnabledStrategy == null) {
			return true;
		}
		return discoveryEnabledStrategy.apply(server);
	}

}
